﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.Reflection;
using System.IO;

namespace Paint
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        #region KhaiBao
        int function = 0;
        int xCuoi, yCuoi;
        bool draw = false;
        Controller controller = new Controller();
        VeTuDo VTD;
        ToMau TM;
        HinhVe HV;
        DuongThang DT;
        HinhChuNhat HCN;
        HinhVuong HVu;
        HinhTron HT;
        VietChu VC = new VietChu();
        #endregion

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HV.MoHinh(panel1, HV);
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HV.LuuHinh(panel1, HV);
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //http://www.codeproject.com/Articles/198419/Painting-on-a-panel
            //kích hoạt chế dộ doubuffer cho panel
            panel1.GetType().GetMethod("SetStyle", BindingFlags.Instance |
                    BindingFlags.NonPublic).Invoke(panel1, new object[] {
                    ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.DoubleBuffer, true });

            HV = new HinhVe() { Bimap = new Bitmap(panel1.Width, panel1.Height) };
            HV.HienThiHinh(panel1, HV);
            fillFontCombo();

            //load thong tin cau hinh
            LoadConfig();
            controller.Change(9, HV, HV.ChoiVe.Color);
            controller.Change(13, VC, HV.ChoiVe.Color);
            controller.Change(11, VC, VC.FontName);

            cbxWeight.SelectedIndex = HV.Weight / 2;
            cbxfont.SelectedItem = VC.FontName;
            cbo_size.SelectedItem = VC.FontSize.ToString();
            //bat xu kien key press cho panel
            this.KeyPress += new KeyPressEventHandler(MyKeyPressEventHandler);

            VC.PanelWith = panel1.Width;
            //bat su kien thay doi mau khi ve text
            VC.FinishDrawTextEvent += new VietChu.FinishDrawText(FinishDrawText);
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (function != 0)
            {
                draw = true;
                switch (function)
                {
                    case 1:
                        VTD = new VeTuDo(HV);
                        VTD.ListPoint.Add(new Point(e.X, e.Y));
                        break;
                    //to mau
                    case 2:
                        TM = new ToMau(HV) { DiemDau = new Point(e.X, e.Y) };
                        controller.Draw(function, TM);
                        draw = false;
                        Refresh();
                        break;
                    case 5:
                        DT = new DuongThang(HV) { DiemDau = new Point(e.X, e.Y) };
                        break;
                    case 6:
                        HT = new HinhTron(HV) { DiemDau = new Point(e.X, e.Y) };
                        break;
                    case 7:
                        HVu = new HinhVuong(HV) { DiemDau = new Point(e.X, e.Y) };
                        break;
                    case 8:
                        HCN = new HinhChuNhat(HV) { DiemDau = new Point(e.X, e.Y) };
                        break;
                    case 100:
                        {
                            if (VC.flag == 2)
                            {
                                VC.PointStart1.X = e.X;
                                VC.PointStart1.Y = e.Y;
                            }
                            else if (VC.flag == 3)
                            {
                                VC.PointStart2.X = e.X;
                                VC.PointStart2.Y = e.Y;
                                VC.flag = 4;
                            }
                            break;
                        }
                }
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (draw == true)
            {
                xCuoi = e.X;
                yCuoi = e.Y;
                FixLocation(ref xCuoi, ref yCuoi);
                switch (function)
                {
                    case 1:
                        VTD.ListPoint.Add(new Point(xCuoi, yCuoi));
                        break;
                    case 5:
                        DT.DiemCuoi = new Point(xCuoi, yCuoi);
                        break;
                    case 6:
                        HT.DiemCuoi = new Point(xCuoi, yCuoi);
                        break;
                    case 7:
                        HVu.DiemCuoi = new Point(xCuoi, yCuoi);
                        break;
                    case 8:
                        HCN.DiemCuoi = new Point(xCuoi, yCuoi);
                        break;
                    case 100:
                        if (VC.flag == 2)
                        {
                            VC.PointEnd1.X = xCuoi;
                            VC.PointEnd1.Y = yCuoi;
                        }
                        else if (VC.flag == 4)
                        {
                            VC.PointEnd2.X = xCuoi;
                            VC.PointEnd2.Y = yCuoi;
                        }
                        break;
                }
                panel1.Refresh();
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (draw == true)
            {
                xCuoi = e.X;
                yCuoi = e.Y;
                FixLocation(ref xCuoi, ref yCuoi);
                switch (function)
                {
                    case 1:
                        VTD.ListPoint.Add(new Point(xCuoi, yCuoi));
                        controller.Draw(function, VTD);
                        VTD.ListPoint.Clear();
                        break;
                    case 5:
                        DT.DiemCuoi = new Point(xCuoi, yCuoi);
                        DT.Graphics = Graphics.FromImage(HV.Bimap);
                        controller.Draw(function, DT);
                        break;
                    case 6:
                        HT.DiemCuoi = new Point(xCuoi, yCuoi);
                        HT.Graphics = Graphics.FromImage(HV.Bimap);
                        controller.Draw(function, HT);
                        break;
                    case 7:
                        HVu.DiemCuoi = new Point(xCuoi, yCuoi);
                        HVu.Graphics = Graphics.FromImage(HV.Bimap);
                        controller.Draw(function, HVu);
                        break;
                    case 8:
                        HCN.DiemCuoi = new Point(xCuoi, yCuoi);
                        HCN.Graphics = Graphics.FromImage(HV.Bimap);
                        controller.Draw(function, HCN);
                        break;
                    case 100:
                        if (VC.flag == 2)// vẽ ô để nhập văn bản
                        {
                            VC.PointEnd1.X = xCuoi;
                            VC.PointEnd1.Y = yCuoi;
                            VC.flag = 3;
                            panel1.Focus();
                            panel1.Refresh();
                            return;
                        }
                        else if (VC.flag == 4)//đã nhập văn bản
                        {
                            VC.PointEnd2.X = xCuoi;
                            VC.PointEnd2.Y = yCuoi;

                            if (VC.PointStart2 == VC.PointEnd2)//không vẽ văn mới-->hoàn thành vẽ văn bản
                            {
                                FinishDrawText();
                                return;
                            }
                            else//ve them văn bản-->hoàn thành vẽ văn bản cũ và vẽ ô để nhập văn bản mới
                            {
                                DuplicateDrawText();
                                return;
                            }
                        }
                        break;
                }
                draw = false;
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (draw == true)
            {
                switch (function)
                {
                    case 1:
                        controller.Draw(function, VTD);
                        break;
                    case 5:
                        DT.Graphics = e.Graphics;
                        controller.Draw(function, DT);
                        break;
                    case 6:
                        HT.Graphics = e.Graphics;
                        controller.Draw(function, HT);
                        break;
                    case 7:
                        HVu.Graphics = e.Graphics;
                        controller.Draw(function, HVu);
                        break;
                    case 8:
                        HCN.Graphics = e.Graphics;
                        controller.Draw(function, HCN);
                        break;
                    case 100:
                        VC.Draw(e.Graphics);
                        break;
                }
            }
        }

        private void panel1_MouseEnter(object sender, EventArgs e)
        {
            switch (function)
            {
                case 1:
                    this.Cursor = ActuallyLoadCursor("../../images/pencil.cur");
                    break;
                case 2:
                    this.Cursor = ActuallyLoadCursor("../../images/color_fill.cur");
                    break;
                case 100:
                    this.Cursor = ActuallyLoadCursor("../../images_cursor/text.cur");
                    break;
            }
        }

        private void panel1_MouseLeave(object sender, EventArgs e)
        {
            Cursor = DefaultCursor;
        }

        #region thay doi mau

        private void btnRed_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Red);
            controller.Change(13, VC, Color.Red);
        }

        private void btnSliver_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Silver);
            controller.Change(13, VC, Color.Silver);
        }

        private void btnDarkOrange_Click(object sender, EventArgs e)
        {

            controller.Change(9, HV, Color.DarkOrange);
            controller.Change(13, VC, Color.DarkOrange);
        }

        private void btnyellow_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Yellow);
            controller.Change(13, VC, Color.Yellow);
        }

        private void btnLime_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Lime);
            controller.Change(13, VC, Color.Lime);
        }

        private void btnCyan_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Cyan);
            controller.Change(13, VC, Color.Cyan);
        }

        private void btnBlue_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Blue);
            controller.Change(13, VC, Color.Blue);
        }

        private void btnFuchsia_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Fuchsia);
            controller.Change(13, VC, Color.Fuchsia);
        }

        private void btnGray_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Gray);
            controller.Change(13, VC, Color.Gray);
        }

        private void btnFirebrick_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Firebrick);
            controller.Change(13, VC, Color.Firebrick);
        }

        private void btnYellowGreen_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.YellowGreen);
            controller.Change(13, VC, Color.YellowGreen);
        }

        private void btnblack_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Black);
            controller.Change(13, VC, Color.Black);
        }

        private void btnLimeGreen_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.LimeGreen);
            controller.Change(13, VC, Color.LimeGreen);
        }

        private void btnLightSeaGreen_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.LightSeaGreen);
            controller.Change(13, VC, Color.LightSeaGreen);
        }

        private void btnDarkBlue_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.DarkBlue);
            controller.Change(13, VC, Color.DarkBlue);
        }

        private void btnViolet_Click(object sender, EventArgs e)
        {
            controller.Change(9, HV, Color.Violet);
            controller.Change(13, VC, Color.Violet);
        }

        private void llbColor_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ColorDialog colorDlg = new ColorDialog();
            if (colorDlg.ShowDialog() == DialogResult.OK)
            {
                controller.Change(9, HV, colorDlg.Color);
                controller.Change(13, VC, colorDlg.Color);
            }

        }
        #endregion thay doi mau

        #region thiet lap chuc nang

        private void btnVeTuDo_Click(object sender, EventArgs e)
        {
            if (function == 100)
            {
                VC.flag = 1;
                VC.Draw(Graphics.FromImage(HV.Bimap));
                panel1.Refresh();
                draw = false;
                //unfocus for panel
                this.ActiveControl = null;
                VC.flag = 2;
            }
            function = 1;//người dùng chọn chức năng vẽ tự do
        }

        private void btnVeDuongThang_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 5;//người dùng chọn chức năng vẽ đường thẳng 
        }

        private void btnVeHinhVuong_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 7;
        }

        private void btnVeHinhTron_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 6;//người dùng chọn chức năng vẽ hình tròn
            //this.Cursor = DefaultCursor;
        }

        private void btnVietChu_Click(object sender, EventArgs e)
        {
            function = 100;
        }

        private void btnVeChuNhat_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 8;//người dùng chọn chức năng vẽ hình chữ nhật
            //this.Cursor = DefaultCursor;
        }

        private void btnToMauNen_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 2;
        }

        private void ttVeTuDo_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 1;//người dùng chọn chức năng vẽ tự do
        }

        private void ttDuongThang_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 5;//người dùng chọn chức năng vẽ đường thẳng 
        }

        private void ttChuNhat_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 8;//người dùng chọn chức năng vẽ hình chữ nhật
            //this.Cursor = DefaultCursor;
        }

        private void ttHinhVuong_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 7;
        }

        private void ttHinhTron_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 6;//người dùng chọn chức năng vẽ hình tròn
            //this.Cursor = DefaultCursor;
        }

        private void ttToMau_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 2;
        }

        private void ttVietChu_Click(object sender, EventArgs e)
        {
            FinishDrawText();
            function = 100;
        }

        #endregion thiet lap chuc nang

        private void cbxfont_SelectedIndexChanged(object sender, EventArgs e)
        {
            controller.Change(11, VC, cbxfont.SelectedItem.ToString());
            if (VC.flag == 3)
            {
                FinishDrawText();
            }
        }

        private void cbxWeight_SelectedIndexChanged(object sender, EventArgs e)
        {
            controller.Change(10, HV, cbxWeight.SelectedIndex * 2 + 1);
            if (VC.flag == 3)
            {
                FinishDrawText();
            }
        }

        private void cbo_size_SelectedIndexChanged(object sender, EventArgs e)
        {
            controller.Change(12, VC, int.Parse(cbo_size.SelectedItem.ToString()));
            if (VC.flag == 3)
            {
                FinishDrawText();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveConfig();
        }

        //in hinh
        private void document_PrintPage(object sender, PrintPageEventArgs e)
        {
            panel1.DrawToBitmap(HV.Bimap, new Rectangle(0, 0, panel1.Width, panel1.Height));
            e.Graphics.DrawImage(HV.Bimap, 0, 0);
        }

        private void printToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            PrintDialog printDialog1 = new PrintDialog();
            PrintDocument prdoc = new PrintDocument();
            prdoc.PrintPage += new PrintPageEventHandler(document_PrintPage);
            printDialog1.ShowNetwork = true;
            printDialog1.Document = prdoc;

            DialogResult result = printDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {

                prdoc.PrinterSettings = printDialog1.PrinterSettings;
                prdoc.DefaultPageSettings.Landscape = true;
                prdoc.Print();
            }
        }

        //xu li bieu tuong chuot
        public Cursor ActuallyLoadCursor(String path)
        {
            return new Cursor(LoadCursorFromFile(path));
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]

        private static extern IntPtr LoadCursorFromFile(string fileName);

        //do du lieu len form
        public void fillFontCombo()
        {
            FontFamily[] families = FontFamily.Families;
            //Loop Through System Fonts
            foreach (FontFamily family in families)
            {
                //Display The Font Combo Items
                cbxfont.Items.Add(family.Name);
            }
        }

        private void cbxWeight_DrawItem(object sender, DrawItemEventArgs e)
        {
            //http://codingjoy.blogspot.com/2006/03/image-combobox-in-c.html
            Pen p = new Pen(Color.Black);
            e.DrawBackground();
            p.Width = e.Index * 2 + 1;
            e.Graphics.DrawLine(p, new PointF(e.Bounds.X, e.Bounds.Y + 7), new PointF(e.Bounds.X + 121, e.Bounds.Y + 7));
            e.DrawFocusRectangle();
        }

        private void LoadConfig()
        {
            StreamReader sr = File.OpenText(Application.StartupPath + "\\config\\profile.txt");
            HV.Weight = int.Parse(sr.ReadLine());
            VC.FontSize = int.Parse(sr.ReadLine());
            VC.FontName = sr.ReadLine();
            HV.ChoiVe = new SolidBrush(Color.FromName(sr.ReadLine()));
            sr.Close();
        }

        private void SaveConfig()
        {
            StreamWriter sw = new StreamWriter(Application.StartupPath + "\\config\\Profile.txt");
            sw.WriteLine(HV.Weight);
            sw.WriteLine(VC.FontSize);
            sw.WriteLine(VC.FontName);
            sw.WriteLine(HV.Color.Name);
            sw.Close();
        }

        //xu li viet chu
        public void MyKeyPressEventHandler(Object sender, KeyPressEventArgs e)
        {
            if (panel1.Focused)
            {
                VC.key = VC.key + e.KeyChar;
                panel1.Refresh();
            }
        }

        private void FixLocation(ref int x, ref int y)
        {
            if (x < 0)
                x = 0;
            else if (x > panel1.Width)
                x = panel1.Width - 1;
            if (y < 0)
                y = 0;
            else if (y > panel1.Height)
                y = panel1.Height - 1;
        }

        private void FinishDrawText()
        {
            if (function == 100)
            {
                VC.flag = 1;
                VC.Draw(Graphics.FromImage(HV.Bimap));
                panel1.Refresh();
                draw = false;
                //unfocus for panel
                this.ActiveControl = null;
                VC.flag = 2;
            }
        }

        private void DuplicateDrawText()
        {
            VC.flag = 1;
            VC.Draw(Graphics.FromImage(HV.Bimap));
            panel1.Refresh();
            VC.flag = 3;
            VC.PointStart1 = VC.PointStart2;
            VC.PointEnd1 = VC.PointEnd2;
            panel1.Refresh();
            if (!panel1.Focused)
            {
                panel1.Focus();
            }
        }
    }
}
